package com.homer.commons.sscpprotocol.client.impl;

import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;

import com.homer.commons.sscpprotocol.client.SocketOptions;

public class SocketOptionsImpl
  implements SocketOptions
{
  private Map<String, SocketModifier> innerOptions = new HashMap();

  public void apply(Socket socket) throws IOException {
    for (SocketModifier socketModifier : this.innerOptions.values())
      socketModifier.process(socket);
  }

  public void setTcpNoDelay(final boolean on) throws SocketException
  {
    this.innerOptions.put("tcpNoDelay", new SocketModifier() {
      public void process(Socket socket) throws IOException {
        socket.setTcpNoDelay(on);
      }
    });
  }

  public void setSoLinger(final boolean on, final int linger) throws SocketException
  {
    this.innerOptions.put("soLinger", new SocketModifier() {
      public void process(Socket socket) throws IOException {
        socket.setSoLinger(on, linger);
      }
    });
  }

  public void setOOBInline(final boolean on) throws SocketException {
    this.innerOptions.put("oOBInline", new SocketModifier() {
      public void process(Socket socket) throws IOException {
        socket.setOOBInline(on);
      }
    });
  }

  public void setSoTimeout(final int timeout) throws SocketException {
    this.innerOptions.put("soTimeout", new SocketModifier() {
      public void process(Socket socket) throws IOException {
        socket.setSoTimeout(timeout);
      }
    });
  }

  public void setSendBufferSize(final int size) throws SocketException {
    this.innerOptions.put("sendBufferSize", new SocketModifier() {
      public void process(Socket socket) throws IOException {
        socket.setSendBufferSize(size);
      }
    });
  }

  public void setReceiveBufferSize(final int size) throws SocketException {
    this.innerOptions.put("receiveBufferSize", new SocketModifier() {
      public void process(Socket socket) throws IOException {
        socket.setReceiveBufferSize(size);
      }
    });
  }

  public void setKeepAlive(final boolean on) throws SocketException {
    this.innerOptions.put("keepAlive", new SocketModifier() {
      public void process(Socket socket) throws IOException {
        socket.setKeepAlive(on);
      }
    });
  }

  public void setReuseAddress(final boolean on) throws SocketException {
    this.innerOptions.put("reuseAddress", new SocketModifier() {
      public void process(Socket socket) throws IOException {
        socket.setReuseAddress(on);
      }
    });
  }

  private static abstract interface SocketModifier
  {
    public abstract void process(Socket paramSocket)
      throws IOException;
  }
}
